<?php
namespace WDB\Query\Element;
use WDB,
    WDB\Exception;

/**
 * Compare query element.
 *
 * Represents generic equality, inequality, arithmetical greater[or equal] and less[or equal].
 *
 * @author Richard Ejem <richard(at)ejem.cz>
 * @package WDB
 */
class Compare extends InfixOperator implements iCondition
{
    const EQ = '=';
    const LT = '<';
    const LTE = '<=';
    const GT = '>';
    const GTE = '>=';
    const NEQ = '!=';

    protected static $supportedOps = array(self::EQ, self::LT, self::LTE, self::GT, self::GTE, self::NEQ);

    /**
     * Factory method creating Equality comparation.
     *
     * @param iExpression left side of compare operator
     * @param iExpression right side of compare operator
     * @return Compare
     */
    public static function Equals(iExpression $expr1, iExpression  $expr2)
    {
        return new self($expr1, $expr2, self::EQ);
    }

    /**
     * Factory method creating Non-equality comparation.
     *
     * @param iExpression left side of compare operator
     * @param iExpression right side of compare operator
     * @return Compare
     */
    public static function NEquals(iExpression $expr1, iExpression $expr2)
    {
        return new self($expr1, $expr2, self::NEQ);
    }

    /**
     * Factory method creating > comparation.
     *
     * @param iExpression left side of compare operator
     * @param iExpression right side of compare operator
     * @return Compare
     */
    public static function Gt(iExpression $expr1, iExpression $expr2)
    {
        return new self($expr1, $expr2, self::GT);
    }

    /**
     * Factory method creating >= comparation.
     *
     * @param iExpression left side of compare operator
     * @param iExpression right side of compare operator
     * @return Compare
     */
    public static function Gte(iExpression $expr1, iExpression $expr2)
    {
        return new self($expr1, $expr2, self::GTE);
    }

    /**
     * Factory method creating < comparation.
     *
     * @param iExpression left side of compare operator
     * @param iExpression right side of compare operator
     * @return Compare
     */
    public static function Lt(iExpression $expr1, iExpression $expr2)
    {
        return new self($expr1, $expr2, self::LTE);
    }

    /**
     * Factory method creating <= comparation.
     *
     * @param iExpression left side of compare operator
     * @param iExpression right side of compare operator
     * @return Compare
     */
    public static function Lte(iExpression $expr1, iExpression $expr2)
    {
        return new self($expr1, $expr2, self::LTE);
    }

    public function toSQL(WDB\SQLDriver\iSQLDriver $driver)
    {
        return $driver->tosql_compare($this->expressions[0], $this->expressions[1], $this->op);
    }

    public function addExpression($expr1)
    {
        throw new Exception\InvalidOperation("Cannot chain comparison operators.");
    }

    /**
     * Create any supported comparation.
     *
     * @param iExpression left side of compare operator
     * @param iExpression right side of compare operator
     * @param string comparation type (enumeration of Compare::*)
     */
    public function __construct(iExpression $expr1, iExpression $expr2, $compare_op = self::EQ)
    {
        parent::__construct(array($expr1, $expr2), $compare_op);
    }
}
